#ifndef NODOBASE_H_
#define NODOBASE_H_
#include "Tipos.h"
#include "ClaveNodo.h"

template<class CClave>
class CNodoBase
{
public:	
	TIPO_DATO nroNodoBloque; //referencia al bloque de indice
	TIPO_DATO cantRegistro;
	TIPO_DATO nivel;		
	TIPO_DATO posicion;//posicion donde encontro
	int m_posicionTrans;//posicion que se usa para el trasformar.
	TIPO_DATO espacioLibre;
	TIPO_DATO totalByte;//este atributo lo carga MARCO despues de trasformar todo	
	bool		m_eliminar;//informa si tengo que eliminar una clave por no tener mas elementos en el vector.	
	CNodoBase();
	virtual ~CNodoBase(){}

	bool esHoja(void);  	//pregunta si el actual es una hoja
	bool sigueHoja(void);	//pregunta si el siguiente es una hoja
 	virtual  bool hayLugar(CClave &claveIn)=0;//{return (espacioLibre >= tamClave);}
	bool vacio(){return cantRegistro==0;}
	bool esRaiz(){return nroNodoBloque== (TIPO_DATO)0;}
	bool esUnderflow();
 	virtual  void insertarOrdenado(CClave& clave,TIPO_DATO nroBloqueViejo,TIPO_DATO nroBloqueNuevo)=0;
 	virtual void clear()=0;
 	//virtual void distribuirClaves(TIPO_DATO &sucesorIzq, TIPO_DATO &sucesorDer,CClave &clave,CNodoBase<CClave> &nodoNuevo)=0;
	virtual bool equilibrarConHrno(TIPO_DATO indice)=0;
	virtual void fusionar(CNodoBase<CClave> &nodoPadre,TIPO_DATO posPadre,CNodoBase<CClave> &nodoHrno)=0;
	virtual void eliminar(TIPO_DATO indice)=0;
	int transformar(string datos,TIPO_DATO &posicion);
	string desTransformar();

	virtual void setCantRegistros(TIPO_DATO cant){cantRegistro = cant;}
	void setPosicion(TIPO_DATO posicion){this->posicion = posicion;};	
 	virtual void setClave(CClave &clave)=0;
	virtual void setClave(CClave &clave,TIPO_DATO posicion)=0;	 	
	void setNivel(TIPO_DATO nivel){this->nivel = nivel;}
	void setNroBloque(TIPO_DATO bloque){nroNodoBloque = bloque;}
   	virtual void setSucesorIzq(TIPO_DATO suc)=0;
  	virtual void setSucesorDer(TIPO_DATO suc,TIPO_DATO indice)=0;
	virtual void setSucesorDer(TIPO_DATO suc)=0;
	virtual void setSigSetSec(TIPO_DATO blqSig)=0;

	bool getEliminar(){return m_eliminar;}
	TIPO_DATO getCantRegistros();//{return this->cantRegistro;}
	virtual TIPO_DATO getTamanio()=0;
	virtual TIPO_DATO getTamanio(int indice)=0;
	
	TIPO_DATO getPosicion(){return posicion;};
	TIPO_DATO getEspacioLibre(){return 	espacioLibre;}	
	TIPO_DATO getTotalByte(){return this->totalByte;}
 	TIPO_DATO getNivel(){return nivel;}
 	TIPO_DATO getNroBloque(){return this->nroNodoBloque;}
	virtual TIPO_DATO getSigSetSec(void)=0;
	virtual CClave* getspClave(TIPO_DATO indice)=0;
	virtual CClaveNodo<CClave> &getClaveNodo(TIPO_DATO indice)=0;
	virtual CClaveNodo<CClave>* getspClaveNodo(TIPO_DATO indice)=0;

	virtual TIPO_DATO getSucesorIzq()=0;
	virtual TIPO_DATO getSucesorDer(int indice)=0;

 	virtual	CClave &getClave(TIPO_DATO indice)=0;
	virtual TIPO_DATO getTamRegistro(TIPO_DATO indice)=0;
	virtual bool obtenerNroBloque(CClave &espacioLibre,TIPO_DATO &nroBloque,fstream &archivo)=0;
	virtual void mostrar()=0; /* = std::cout*/
	virtual void ordenar()=0;
  //  void trasformar(char dato[TAMANIO_NODO],int posicion);
	virtual void insertarVectorSec(CClave &clave,fstream &archivo)=0;
	virtual bool cambiarClave(CClave &claveVieja,CClave &claveNueva)=0;
	virtual bool eliminarElemVector(TIPO_DATO claveIn,fstream &archivo)=0;
	virtual bool puedoFusionar(TIPO_DATO tamHermano,TIPO_DATO tamClave)=0;
	virtual void intercambiar(CNodoBase<CClave> &nodoHrno,bool hrnoDerecho,CNodoBase<CClave> &nodoPadre,TIPO_DATO posPadre)=0;
};
/*-----------------------------------------------------------*/
template<class CClave>
CNodoBase<CClave>::CNodoBase(void)
{	
	nroNodoBloque=0; //referencia al bloque de indice
	cantRegistro=0;
	m_eliminar = false;	
	nivel=0;		
	posicion=0;//posicion donde encontro
	m_posicionTrans=0;//posicion que se usa para el trasformar.
	espacioLibre=TAMANIO_NODO - TAMANIO_CANTIDAD_REGISTRO -TAMANIO_NIVEL;
	totalByte=0;//este atributo lo carga MARCO despues de trasformar todo		
	
}
/*-----------------------------------------------------------*/
template<class CClave>
bool CNodoBase<CClave>::esHoja(void)
{	//VER, esta bien poner .nivel
	return ( nivel == 0 );
}
/*-----------------------------------------------------------*/
/*llega toda la tira de byte*/
template<class CClave>
int CNodoBase<CClave>::transformar(string datos, TIPO_DATO &posicion)
{
	if(datos.compare("")==0)
	{
	//cargas los atributos de esta clase.
		nroNodoBloque = 0; 
		cantRegistro = 0; 
		nivel = 0; 
		//espacioLibre = TAMANIO_NODO - TAMANIO_CANTIDAD_REGISTRO - TAMANIO_NIVEL;
	}
	else
	{
		nroNodoBloque = 0; 
		cantRegistro = string2TipoDato(datos.substr(0,TAMANIO_CANTIDAD_REGISTRO)); 
		nivel = string2TipoDato(datos.substr(TAMANIO_CANTIDAD_REGISTRO,TAMANIO_NIVEL)); 
		//espacioLibre -= (TAMANIO_CANTIDAD_REGISTRO + TAMANIO_NIVEL);
	}
	return posicion = TAMANIO_CANTIDAD_REGISTRO + TAMANIO_NIVEL;
}
/*-----------------------------------------------------------*/
template<class CClave>
string CNodoBase<CClave>::desTransformar()
{
//	char numero[10];
	string dato="";
	//dato+=(string)itoa(cantRegistro,numero,10);
	//dato+=(string)itoa(nivel,numero,10);
	dato+=convertirChar(cantRegistro,TAMANIO_CANTIDAD_REGISTRO);
	dato+=convertirChar(nivel,TAMANIO_NIVEL);
	return dato;
}
/*-----------------------------------------------------------*/
template<class CClave>
bool CNodoBase<CClave>::sigueHoja(void)
{	//VER, esta bien poner .nivel
	return ( nivel == 1 );
}
/*-----------------------------------------------------------*/
template<class CClave>
bool CNodoBase<CClave>::esUnderflow()
{
	TIPO_DATO porcentaje;
	
	porcentaje = (TIPO_DATO)(((double)(this->espacioLibre)/TAMANIO_NODO)*100);
	if(porcentaje<PORCENTAJE_MINIMO)
		return false;
	return true;
}
/*-----------------------------------------------------------*/
template<class CClave>
TIPO_DATO CNodoBase<CClave>::getCantRegistros()
{
	return this->cantRegistro;
}

#endif /*NODOBASE_H_*/
